/*
 * @copyright 2010 Gerald Jacobson
 * @license GNU General Public License
 * 
 * This file is part of Descent Assistant.
 *
 * Descent Assistant is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Descent Assistant is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Descent Assistant.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.amphiprion.descenttool.control;

import org.amphiprion.descenttool.control.ControlerState.ClickMode;

import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;

/**
 * @author Amphiprion
 * 
 */
public class TouchControler {
	private Object mutex = new Object();
	private ControlerState controlState = new ControlerState();
	private boolean moving;
	private volatile long lastDownTime = 0;

	public TouchControler(View view) {
		view.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				// Log.d("com.amphiprion.westeros", "mode=" + mode + "  index="
				// + event.getActionIndex() + "  down=" + event.getAction());
				// int index = event.getActionIndex();
				synchronized (mutex) {

					int actionCode = event.getAction();
					final float x = event.getX();
					final float y = event.getY();

					switch (actionCode) {
					case MotionEvent.ACTION_DOWN:

						long time = System.currentTimeMillis();
						if (time - lastDownTime < 250) {
							controlState.click = ClickMode.DOUBLE_CLICK;
							controlState.touched = false;
						} else {
							controlState.click = ClickMode.DOWN;
							lastDownTime = time;
							controlState.touched = true;
						}
						controlState.position.x = (int) x;
						controlState.position.y = (int) y;
						controlState.translate.x = 0;
						controlState.translate.y = 0;
						break;
					case MotionEvent.ACTION_UP:

						if (controlState.click == ClickMode.NONE || controlState.click == ClickMode.DOWN) {
							controlState.click = ClickMode.CLICK;
						}

						controlState.position.x = (int) x;
						controlState.position.y = (int) y;
						controlState.translate.x = 0;
						controlState.translate.y = 0;
						controlState.touched = false;
						moving = false;
						break;
					case MotionEvent.ACTION_MOVE:
						if (controlState.touched) {
							int dx = (int) x - controlState.position.x;
							int dy = (int) y - controlState.position.y;
							if (!moving && (Math.abs(dx) > 8 || Math.abs(dy) > 8)) {
								moving = true;
							}
							if (moving) {
								controlState.translate.x += dx;
								controlState.translate.y += dy;
								controlState.position.x = (int) x;
								controlState.position.y = (int) y;
							}
						}
						break;
					}
				}

				return true;
			}
		});
	}

	public ControlerState getControlerState() {
		ControlerState state = null;
		synchronized (mutex) {
			if (!moving && controlState.touched && System.currentTimeMillis() - lastDownTime > 500) {
				controlState.click = ClickMode.LONG_CLICK;
				controlState.touched = false;
			}
			state = new ControlerState(controlState);

			controlState.click = ClickMode.NONE;
			controlState.translate.x = 0;
			controlState.translate.y = 0;
		}
		return state;
	}
}
